package sample.plugin.http.window;

import android.graphics.drawable.Drawable;

import com.qiplat.open.ui.widget.dialog.QiLoadingDialog;
import com.rapid.android.ui.widget.editor.QiCodeEditor;
import com.rapid.api.component.widget.window.Window;
import com.rapid.api.component.widget.window.Windows;
import com.rapid.api.ext.framework.BaseEvent;
import com.rapid.api.ext.plugin.AndroidPlugins;
import com.rapid.api.framework.domain.window.WindowEvent;
import com.rapid.api.framework.domain.window.WindowService;
import com.rapid.framework.extension.SafeCommand;
import com.rapid.framework.vfs.VirtualFile;
import com.rapid.util.android.ContextUtils;

import java.io.IOException;

import io.github.rosemoe.sora.event.SideIconClickEvent;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import sample.plugin.http.R;
import sample.plugin.http.lang.RequestLanguage;
import sample.plugin.http.entity.RequestEntity;

public class RequestWindowEvent extends BaseEvent implements WindowEvent {
    private final static MediaType CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded");
    private final static MediaType JSON_TYPE = MediaType.parse("application/json");

    public static Drawable runDrawable;
    private RequestEntity entity;
    private final WindowService windowService;

    public RequestWindowEvent(WindowService windowService) {
        this.windowService = windowService;
        runDrawable = ContextUtils.getDrawable(
                AndroidPlugins.getContext(this),
                R.drawable.ic_run
        );
    }

    @Override
    public void onWindowCreate(Window window, VirtualFile virtualFile) {
        if (!(window instanceof QiCodeEditor)) {
            return;
        }
        QiCodeEditor editor = (QiCodeEditor) window;
        String extension = virtualFile.getExtension();
        if (!"req".equals(extension)) {
            return;
        }
        editor.subscribeEvent(SideIconClickEvent.class, (event, unsubscribe) -> {
            int line = event.getClickedIcon().getLine();
            RequestLanguage language = (RequestLanguage) editor.getEditorLanguage();
            entity = language.getAnalyzeManager().getDecision().getRequestModel(line);
            if (entity != null) {
                DoRequestVirtualFile requestSession = new DoRequestVirtualFile(entity.name);
                windowService.openVirtualFile(requestSession, DoRequestVirtualFile.CHANNEL_DO_REQUEST);
            }
        });
    }

    @Override
    public void onWindowAdd(Window window) {

    }

    @Override
    public void onWindowSelect(Window window) {
        if (entity == null) {
            return;
        }
        if (!DoRequestVirtualFile.CHANNEL_DO_REQUEST.equals(window.getChannel())) {
            return;
        }
        if (!(window instanceof QiCodeEditor)) {
            return;
        }
        QiCodeEditor editor = (QiCodeEditor) window;
        editor.hideSoftInput();
        try {
            doRequest(editor);
        } catch (Exception e) {
            entity = null;
            SafeCommand.run(this, ignore -> {
                throw new RuntimeException(e);
            });
        }
    }

    @Override
    public void onWindowRemove(Window window) {

    }

    @Override
    public void onSave(Windows windows, boolean b) {

    }

    private void doRequest(QiCodeEditor editor) {
        QiLoadingDialog dialog = new QiLoadingDialog(getActivity());
        dialog.setTitle("请求中");
        dialog.setTipText("正在请求" + entity.url);
        dialog.setCancelable(true);
        OkHttpClient client = new OkHttpClient.Builder().build();
        Request.Builder builder = new Request.Builder();
        builder.url(entity.url);
        if (entity.headers != null) {
            builder.headers(Headers.of(entity.headers));
        }
        switch (entity.kind) {
            case GET:
                builder.get();
                break;
            case POST:
                builder.post(genRequestBody(entity.param));
                break;
            case PUT:
                builder.put(genRequestBody(entity.param));
                break;
            case DELETE:
                builder.delete(genRequestBody(entity.param));
                break;
        }
        Request request = builder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                entity = null;
                getActivity().runOnUiThread(() -> {
                    dialog.dismiss();
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                entity = null;
                String content = response.body().string();
                getActivity().runOnUiThread(() -> {
                    String result = "";
                    result += "响应码：" + response.code() + "\n\n";
                    result += "响应头：\n";
                    Headers headers = response.headers();
                    int headerSize = headers.size();
                    for (int i = 0; i < headerSize; i++) {
                        result += headers.name(i) + ": " + headers.value(i);
                        result += "\n";
                    }
                    result += "\n响应体：\n";
                    result += content;
                    editor.setText(result);
                    editor.hideSoftInput();
                    dialog.dismiss();
                });
            }
        });
    }

    private RequestBody genRequestBody(String param) {
        if (param.charAt(0) == '{') {
            return RequestBody.create(JSON_TYPE, param);
        } else {
            return RequestBody.create(CONTENT_TYPE, param);
        }
    }
}
